1. Set working directory
setwd("~/Library/CloudStorage/OneDrive-UniversityofEdinburgh/4th year/dissertation/dissertation")
  1. Load packages
library(skimr)  # summary
library(tidyverse)
library(lubridate)  # dates management
library(gridExtra)  # arrange plots
library(patchwork)  # combine plots

2.2. Creates functions

theme_graphs_env_cond <- function(){
  theme_classic() +
  theme(axis.text.x = element_text(angle = 90))+
   theme(axis.text = element_text(size = 11),  # Adjust the size as needed
          axis.title = element_text(size = 18),
        legend.text = element_text(size=14))
  }
  1. Load the data and see its structure
data <- read.csv("Data_PAM_Scott_Base.csv") # load data
skimr::skim(data)  # see a summary of the whole data
── Data Summary ────────────────────────
                           Values
Name                       data  
Number of rows             26722 
Number of columns          43    
_______________________          
Column type frequency:           
  character                9     
  numeric                  34    
________________________         
Group variables            None  
str(data)  # see the structure of each variable
'data.frame':   26722 obs. of  43 variables:
 $ Datetime        : chr  "17/01/2019 04:17" "17/01/2019 05:17" "17/01/2019 06:17" "17/01/2019 07:17" ...
 $ Time..abs.ms.   : num  1.55e+12 1.55e+12 1.55e+12 1.55e+12 1.55e+12 ...
 $ Time..rel.ms.   : num  15441000 19041000 22641000 26241000 29841000 ...
 $ JD.nz           : num  17.7 17.7 17.8 17.8 17.8 ...
 $ JD.running.nz   : num  17.7 17.7 17.8 17.8 17.8 ...
 $ Year.percent.nz : num  4.83 4.84 4.85 4.86 4.88 ...
 $ Dec.Year.nz     : num  19 19 19 19 19 ...
 $ Date            : chr  "43482" "43482" "43482" "43482" ...
 $ Time            : chr  "0.1787" "0.2204" "0.2620" "0.3037" ...
 $ Julian.Day.UTC  : num  17.2 17.2 17.3 17.3 17.3 ...
 $ JD.running.UTC  : num  17.2 17.2 17.3 17.3 17.3 ...
 $ Year.percent.UTC: num  4.69 4.71 4.72 4.73 4.74 ...
 $ UTC             : num  19 19 19 19 19 ...
 $ No.             : int  1 2 3 4 5 6 7 8 9 10 ...
 $ X1.F            : int  106 120 127 119 79 118 93 90 107 96 ...
 $ X1.Fm.          : int  172 203 234 210 103 202 134 134 186 162 ...
 $ X1.PAR          : int  543 557 623 692 1335 352 689 815 376 569 ...
 $ X1.Temp         : num  2.3 1 -0.9 -0.9 -0.2 -1.7 -0.7 -0.2 -2.2 -0.7 ...
 $ X1.Y..II.       : num  0.384 0.409 0.457 0.433 0.233 0.416 0.306 0.328 0.425 0.407 ...
 $ diff            : int  66 83 107 91 24 84 41 44 79 66 ...
 $ X               : chr  "0.384" "0.409" "0.457" "0.433" ...
 $ X1.ETR          : num  87.4 95.5 119.3 125.6 130.3 ...
 $ X2.F            : int  133 114 157 138 132 143 125 143 137 115 ...
 $ X2.Fm.          : int  179 163 268 217 200 235 202 266 256 213 ...
 $ X2.PAR          : int  994 971 712 534 774 330 460 316 257 358 ...
 $ X2.Temp         : num  2 2 1 -0.2 1.3 -0.7 -0.4 -1.2 -1.4 -1.2 ...
 $ X2.Y..II.       : num  0.257 0.301 0.414 0.364 0.34 0.391 0.381 0.462 0.465 0.46 ...
 $ diff.1          : int  46 49 111 79 68 92 77 123 119 98 ...
 $ X2.ETR          : num  107 122.5 123.5 81.4 110.3 ...
 $ X3.F            : chr  "51" "54" "47" "43" ...
 $ X3.Fm.          : chr  "58" "57" "50" "51" ...
 $ X3.PAR          : chr  "384" "381" "159" "257" ...
 $ X3.Temp         : chr  "-1.2" "-1.9" "-3.9" "-3.9" ...
 $ X3.Y..II.       : num  0 0 0 0 0 0 0 0 0 0 ...
 $ diff.2          : chr  "7" "3" "3" "8" ...
 $ X3.ETR          : num  0 0 0 0 0 0 0 0 0 0 ...
 $ X4.F            : int  48 48 49 44 50 50 46 53 54 51 ...
 $ X4.Fm.          : int  70 67 69 64 63 77 68 86 85 81 ...
 $ X4.PAR          : int  532 787 842 444 1472 356 689 796 363 572 ...
 $ X4.Temp         : num  1.8 1.5 1.5 1 3 -1.4 -0.9 -1.2 -1.9 -0.7 ...
 $ X4.Y..II.       : num  0.314 0.284 0.29 0.313 0.206 0.351 0.324 0.384 0.365 0.37 ...
 $ X4.ETR          : num  70 93.7 102.3 58.2 127.1 ...
 $ diff.3          : int  22 19 20 20 13 27 22 33 31 30 ...
tail(data)  # view the last 6 rows of data
head(data)  # view the first 6 rows of data

Data of sensors 1,2 and 4 are for the moss and 3 is for the lichen. Data is from Jan 2019 to Feb 2022. I am going to consider summer form 1 Nov to 15 Feb. I currently have data for 3 summers: 2019-2020, 2020-2021, 2021-2022.

4. Format data in a way that is going to be useful to me

4.1. Remove weird times and dates and divide the useful ones

data_clean <- data[, -c(2:13)] %>%   # create a new data set without columns 2 to 13
  mutate(Day_cum = as.numeric(data$Date)) # maintain cumulative date but change column name to more informative one and make it numeric
Warning: There was 1 warning in `mutate()`.
ℹ In argument: `Day_cum = as.numeric(data$Date)`.
Caused by warning:
! NAs introduced by coercion
data_clean <- data_clean %>% 
  mutate(Date = parse_date_time(Datetime, 'dmy HM'))   # indicate the format the date is wanted
Warning: There was 1 warning in `mutate()`.
ℹ In argument: `Date = parse_date_time(Datetime, "dmy HM")`.
Caused by warning:
!  1 failed to parse.
print(data_clean[is.na(data_clean$Date), ])  # Check for rows with parsing issues\
#  Row 584 is problematic

data_clean[584, 1]<-"10/02/2019 10:08"  # Change the value to the correct one 

data_clean <- data_clean %>% 
  mutate(Date = parse_date_time(Datetime, 'dmy HM'))   # repeat with all the lines working

data_clean <- data_clean %>%  # create new columns with month, year,
  mutate(Month = month(Date), # day, minute                     
         Year = year(Date),
         Day = day(Date),
         Hour = hour(Date), 
         Minute = minute(Date))

data_clean[584,]  # check it worked
NA

4.2. Check the new data

str(data_clean)
skimr::skim(data_clean)

4.3. Change the diff columns names to match the rest of columns


data_clean<-data_clean %>% 
  rename(X1.diff = diff,
         X2.diff = diff.1,
         X3.diff = diff.2,
         X4.diff = diff.3)

4.4. Need to change some variables of format


data_clean <- data_clean %>%
  mutate(X1.PAR = as.numeric(X1.PAR),  # Change PAR of X1, X2 and X3 to numeric
         X2.PAR = as.numeric(X2.PAR), 
         X3.PAR = as.numeric(X3.PAR), 
         X4.PAR = as.numeric(X4.PAR),
         X3.F = as.numeric(X3.F),  # Change F and Fm to numeric
         X3.Fm. = as.numeric(X3.Fm.),
         X3.Temp = as.numeric(X3.Temp),  # Change Temp 3 to numeric
         X1.diff = as.numeric(X1.diff),  # Change all diff to numeric
         X2.diff = as.numeric(X2.diff),
         X3.diff = as.numeric(X3.diff),
         X4.diff = as.numeric(X4.diff))
         #Month = as.factor(Month),  # Change day, month and year to categories -> is it a great idea?
         #Year = as.factor(Year), 
         #Day = as.factor(Day))

4.5. Create column for month (in letters) and day-month

data_clean <- data_clean %>% 
  mutate(Month_Name = as.factor(case_when(  # Make a column with the names of the months and make them a factor
  Month == 1 ~ "Jan",  # case_when from dplyr package
  Month == 2 ~ "Feb",
  Month == 3 ~ "Mar",
  Month == 4 ~ "Apr",
  Month == 5 ~ "May",
  Month == 6 ~ "Jun",
  Month == 7 ~ "Jul",
  Month == 8 ~ "Aug",
  Month == 9 ~ "Sep",
  Month == 10 ~ "Oct",
  Month == 11 ~ "Nov",
  Month == 12 ~ "Dec"))) %>% 
  mutate(Date_Combined = as.factor(  # Make a column with the day and month name separated by -
    paste(Month_Name, Day, sep = "-")))  # Make the column a factor

4.6. Fix Day_cum

print(data_clean[is.na(data_clean$Day_cum), ])  # Check for rows with NAs in Day_cum

# From 25/01/2022 the date format changes and it is not cummulative anymore

data_clean <- data_clean %>%
  mutate(Date_no_time = paste(year(Date), month(Date), day(Date), sep = "-")) %>%  # Create acolumn with the date but without the time
  mutate(Day_cum = if_else(No. >= 26510, 44586 + as.numeric(difftime(Date_no_time, as.Date("2022-01-25"), units = "days")), Day_cum)) %>%  # Fix the format of Day_cum after the 25/01/2022
  # Difftime weeks the time passed between 2 days in the units indicated
  select(-Date_no_time)  # Remove Date_no_time from the data set
  
print(data_clean[is.na(data_clean$Day_cum), ])  # Check for rows with NAs in Day_cum

head(data_clean$Date_Combined)  # Check it worked
[1] Jan-17 Jan-17 Jan-17 Jan-17 Jan-17 Jan-17
366 Levels: Apr-1 Apr-10 Apr-11 Apr-12 Apr-13 Apr-14 Apr-15 Apr-16 Apr-17 Apr-18 Apr-19 Apr-2 ... Sep-9
tail(data_clean$Date_Combined)
[1] Feb-3 Feb-3 Feb-3 Feb-3 Feb-3 Feb-3
366 Levels: Apr-1 Apr-10 Apr-11 Apr-12 Apr-13 Apr-14 Apr-15 Apr-16 Apr-17 Apr-18 Apr-19 Apr-2 ... Sep-9

4.7. Create a column for average moss values of yield,PAR, F, Fm, Temp, ETR and diff

data_clean <- data_clean %>% 
  mutate(av_moss_yield = rowMeans(data_clean[, c("X1.Y..II.", "X2.Y..II.", "X4.Y..II.")]),  # rowMeans gets the mean of each row in the data frame and stores the result in a new column
         av_moss_PAR = rowMeans(data_clean[, c("X1.PAR", "X2.PAR", "X4.PAR")]),
         av_moss_F = rowMeans(data_clean[, c("X1.F", "X2.F", "X4.F")]),
         av_moss_Fm = rowMeans(data_clean[, c("X1.Fm.", "X2.Fm.", "X4.Fm.")]),
         av_moss_temp = rowMeans(data_clean[, c("X1.Temp", "X2.Temp", "X4.Temp")]),
         av_moss_ETR = rowMeans(data_clean[, c("X1.ETR", "X2.ETR", "X4.ETR")]),
         av_moss_diff = rowMeans(data_clean[, c("X1.diff", "X2.diff", "X4.diff")]))

5. Subset data for summers 2019-2020, 2020-2021, 2021-2022

Summer 2019-2020

This includes the data from the 1-Nov 2019 to the 15 of Feb 2020

summer_19_20 <- data_clean %>% 
  filter(Year == 2019 & Month %in% c(11,12) |  # Filter all data points in Nov, Dec 2019 and Jan, Feb 2020
           Year == 2020 & Month %in% c(1,2)) %>% 
  filter(!(Month == 2 & Day > 15))  # remove days over the 15th of Feb

# Check our data

head(summer_19_20)  # First 6 rows 
tail(summer_19_20)  # Last 6 rows

summer_19_20$Date_Combined <- reorder(summer_19_20$Date_Combined, summer_19_20$Day_cum)  # reorder the factors of Date_Combined according to the values of Day_cum. Do it for each subset individually because factors repeat for each year

levels(summer_19_20$Date_Combined)
  [1] "Nov-1"  "Nov-2"  "Nov-3"  "Nov-4"  "Nov-5"  "Nov-6"  "Nov-7"  "Nov-8"  "Nov-9"  "Nov-10" "Nov-11"
 [12] "Nov-12" "Nov-13" "Nov-14" "Nov-15" "Nov-16" "Nov-17" "Nov-18" "Nov-19" "Nov-20" "Nov-21" "Nov-22"
 [23] "Nov-23" "Nov-24" "Nov-25" "Nov-26" "Nov-27" "Nov-28" "Nov-29" "Nov-30" "Dec-1"  "Dec-2"  "Dec-3" 
 [34] "Dec-4"  "Dec-5"  "Dec-6"  "Dec-7"  "Dec-8"  "Dec-9"  "Dec-10" "Dec-11" "Dec-12" "Dec-13" "Dec-14"
 [45] "Dec-15" "Dec-16" "Dec-17" "Dec-18" "Dec-19" "Dec-20" "Dec-21" "Dec-22" "Dec-23" "Dec-24" "Dec-25"
 [56] "Dec-26" "Dec-27" "Dec-28" "Dec-29" "Dec-30" "Dec-31" "Jan-1"  "Jan-2"  "Jan-3"  "Jan-4"  "Jan-5" 
 [67] "Jan-6"  "Jan-7"  "Jan-8"  "Jan-9"  "Jan-10" "Jan-11" "Jan-12" "Jan-13" "Jan-14" "Jan-15" "Jan-16"
 [78] "Jan-17" "Jan-18" "Jan-19" "Jan-20" "Jan-21" "Jan-22" "Jan-23" "Jan-24" "Jan-25" "Jan-26" "Jan-27"
 [89] "Jan-28" "Jan-29" "Jan-30" "Jan-31" "Feb-1"  "Feb-2"  "Feb-3"  "Feb-4"  "Feb-5"  "Feb-6"  "Feb-7" 
[100] "Feb-8"  "Feb-9"  "Feb-10" "Feb-11" "Feb-12" "Feb-13" "Feb-14" "Feb-15" "Apr-1"  "Apr-10" "Apr-11"
[111] "Apr-12" "Apr-13" "Apr-14" "Apr-15" "Apr-16" "Apr-17" "Apr-18" "Apr-19" "Apr-2"  "Apr-20" "Apr-21"
[122] "Apr-22" "Apr-23" "Apr-24" "Apr-25" "Apr-26" "Apr-27" "Apr-28" "Apr-29" "Apr-3"  "Apr-30" "Apr-4" 
[133] "Apr-5"  "Apr-6"  "Apr-7"  "Apr-8"  "Apr-9"  "Aug-1"  "Aug-10" "Aug-11" "Aug-12" "Aug-13" "Aug-14"
[144] "Aug-15" "Aug-16" "Aug-17" "Aug-18" "Aug-19" "Aug-2"  "Aug-20" "Aug-21" "Aug-22" "Aug-23" "Aug-24"
[155] "Aug-25" "Aug-26" "Aug-27" "Aug-28" "Aug-29" "Aug-3"  "Aug-30" "Aug-31" "Aug-4"  "Aug-5"  "Aug-6" 
[166] "Aug-7"  "Aug-8"  "Aug-9"  "Feb-16" "Feb-17" "Feb-18" "Feb-19" "Feb-20" "Feb-21" "Feb-22" "Feb-23"
[177] "Feb-24" "Feb-25" "Feb-26" "Feb-27" "Feb-28" "Feb-29" "Jul-1"  "Jul-10" "Jul-11" "Jul-12" "Jul-13"
[188] "Jul-14" "Jul-15" "Jul-16" "Jul-17" "Jul-18" "Jul-19" "Jul-2"  "Jul-20" "Jul-21" "Jul-22" "Jul-23"
[199] "Jul-24" "Jul-25" "Jul-26" "Jul-27" "Jul-28" "Jul-29" "Jul-3"  "Jul-30" "Jul-31" "Jul-4"  "Jul-5" 
[210] "Jul-6"  "Jul-7"  "Jul-8"  "Jul-9"  "Jun-1"  "Jun-10" "Jun-11" "Jun-12" "Jun-13" "Jun-14" "Jun-15"
[221] "Jun-16" "Jun-17" "Jun-18" "Jun-19" "Jun-2"  "Jun-20" "Jun-21" "Jun-22" "Jun-23" "Jun-24" "Jun-25"
[232] "Jun-26" "Jun-27" "Jun-28" "Jun-29" "Jun-3"  "Jun-30" "Jun-4"  "Jun-5"  "Jun-6"  "Jun-7"  "Jun-8" 
[243] "Jun-9"  "Mar-1"  "Mar-10" "Mar-11" "Mar-12" "Mar-13" "Mar-14" "Mar-15" "Mar-16" "Mar-17" "Mar-18"
[254] "Mar-19" "Mar-2"  "Mar-20" "Mar-21" "Mar-22" "Mar-23" "Mar-24" "Mar-25" "Mar-26" "Mar-27" "Mar-28"
[265] "Mar-29" "Mar-3"  "Mar-30" "Mar-31" "Mar-4"  "Mar-5"  "Mar-6"  "Mar-7"  "Mar-8"  "Mar-9"  "May-1" 
[276] "May-10" "May-11" "May-12" "May-13" "May-14" "May-15" "May-16" "May-17" "May-18" "May-19" "May-2" 
[287] "May-20" "May-21" "May-22" "May-23" "May-24" "May-25" "May-26" "May-27" "May-28" "May-29" "May-3" 
[298] "May-30" "May-31" "May-4"  "May-5"  "May-6"  "May-7"  "May-8"  "May-9"  "Oct-1"  "Oct-10" "Oct-11"
[309] "Oct-12" "Oct-13" "Oct-14" "Oct-15" "Oct-16" "Oct-17" "Oct-18" "Oct-19" "Oct-2"  "Oct-20" "Oct-21"
[320] "Oct-22" "Oct-23" "Oct-24" "Oct-25" "Oct-26" "Oct-27" "Oct-28" "Oct-29" "Oct-3"  "Oct-30" "Oct-31"
[331] "Oct-4"  "Oct-5"  "Oct-6"  "Oct-7"  "Oct-8"  "Oct-9"  "Sep-1"  "Sep-10" "Sep-11" "Sep-12" "Sep-13"
[342] "Sep-14" "Sep-15" "Sep-16" "Sep-17" "Sep-18" "Sep-19" "Sep-2"  "Sep-20" "Sep-21" "Sep-22" "Sep-23"
[353] "Sep-24" "Sep-25" "Sep-26" "Sep-27" "Sep-28" "Sep-29" "Sep-3"  "Sep-30" "Sep-4"  "Sep-5"  "Sep-6" 
[364] "Sep-7"  "Sep-8"  "Sep-9" 

Summer 2020-2021

This includes the data from the 1-Nov 2020 to the 15 of Feb 2021

summer_20_21 <- data_clean %>% 
  filter(Year == 2020 & Month %in% c(11,12) |  # Filter all data points in Nov, Dec 2029 and Jan, Feb 2021
           Year == 2021 & Month %in% c(1,2)) %>% 
  filter(!(Month == 2 & Day > 15))  # remove days over the 15th of Feb

# Check our data

head(summer_20_21)  # First 6 rows 
tail(summer_20_21)  # Last 6 rows

summer_20_21$Date_Combined <- reorder(summer_20_21$Date_Combined, summer_20_21$Day_cum)  # reorder the factors of Date_Combined according to the values of Day_cum. Do it for each subset individually because factors repeat for each year

levels(summer_20_21$Date_Combined)
  [1] "Nov-1"  "Nov-2"  "Nov-3"  "Nov-4"  "Nov-5"  "Nov-6"  "Nov-7"  "Nov-8"  "Nov-9"  "Nov-10" "Nov-11"
 [12] "Nov-12" "Nov-13" "Nov-14" "Nov-15" "Nov-16" "Nov-17" "Nov-18" "Nov-19" "Nov-20" "Nov-21" "Nov-22"
 [23] "Nov-23" "Nov-24" "Nov-25" "Nov-26" "Nov-27" "Nov-28" "Nov-29" "Nov-30" "Dec-1"  "Dec-2"  "Dec-3" 
 [34] "Dec-4"  "Dec-5"  "Dec-6"  "Dec-7"  "Dec-8"  "Dec-9"  "Dec-10" "Dec-11" "Dec-12" "Dec-13" "Dec-14"
 [45] "Dec-15" "Dec-16" "Dec-17" "Dec-18" "Dec-19" "Dec-20" "Dec-21" "Dec-22" "Dec-23" "Dec-24" "Dec-25"
 [56] "Dec-26" "Dec-27" "Dec-28" "Dec-29" "Dec-30" "Dec-31" "Jan-1"  "Jan-2"  "Jan-3"  "Jan-4"  "Jan-5" 
 [67] "Jan-6"  "Jan-7"  "Jan-8"  "Jan-9"  "Jan-10" "Jan-11" "Jan-12" "Jan-13" "Jan-14" "Jan-15" "Jan-16"
 [78] "Jan-17" "Jan-18" "Jan-19" "Jan-20" "Jan-21" "Jan-22" "Jan-23" "Jan-24" "Jan-25" "Jan-26" "Jan-27"
 [89] "Jan-28" "Jan-29" "Jan-30" "Jan-31" "Feb-1"  "Feb-2"  "Feb-3"  "Feb-4"  "Feb-5"  "Feb-6"  "Feb-7" 
[100] "Feb-8"  "Feb-9"  "Feb-10" "Feb-11" "Feb-12" "Feb-13" "Feb-14" "Feb-15" "Apr-1"  "Apr-10" "Apr-11"
[111] "Apr-12" "Apr-13" "Apr-14" "Apr-15" "Apr-16" "Apr-17" "Apr-18" "Apr-19" "Apr-2"  "Apr-20" "Apr-21"
[122] "Apr-22" "Apr-23" "Apr-24" "Apr-25" "Apr-26" "Apr-27" "Apr-28" "Apr-29" "Apr-3"  "Apr-30" "Apr-4" 
[133] "Apr-5"  "Apr-6"  "Apr-7"  "Apr-8"  "Apr-9"  "Aug-1"  "Aug-10" "Aug-11" "Aug-12" "Aug-13" "Aug-14"
[144] "Aug-15" "Aug-16" "Aug-17" "Aug-18" "Aug-19" "Aug-2"  "Aug-20" "Aug-21" "Aug-22" "Aug-23" "Aug-24"
[155] "Aug-25" "Aug-26" "Aug-27" "Aug-28" "Aug-29" "Aug-3"  "Aug-30" "Aug-31" "Aug-4"  "Aug-5"  "Aug-6" 
[166] "Aug-7"  "Aug-8"  "Aug-9"  "Feb-16" "Feb-17" "Feb-18" "Feb-19" "Feb-20" "Feb-21" "Feb-22" "Feb-23"
[177] "Feb-24" "Feb-25" "Feb-26" "Feb-27" "Feb-28" "Feb-29" "Jul-1"  "Jul-10" "Jul-11" "Jul-12" "Jul-13"
[188] "Jul-14" "Jul-15" "Jul-16" "Jul-17" "Jul-18" "Jul-19" "Jul-2"  "Jul-20" "Jul-21" "Jul-22" "Jul-23"
[199] "Jul-24" "Jul-25" "Jul-26" "Jul-27" "Jul-28" "Jul-29" "Jul-3"  "Jul-30" "Jul-31" "Jul-4"  "Jul-5" 
[210] "Jul-6"  "Jul-7"  "Jul-8"  "Jul-9"  "Jun-1"  "Jun-10" "Jun-11" "Jun-12" "Jun-13" "Jun-14" "Jun-15"
[221] "Jun-16" "Jun-17" "Jun-18" "Jun-19" "Jun-2"  "Jun-20" "Jun-21" "Jun-22" "Jun-23" "Jun-24" "Jun-25"
[232] "Jun-26" "Jun-27" "Jun-28" "Jun-29" "Jun-3"  "Jun-30" "Jun-4"  "Jun-5"  "Jun-6"  "Jun-7"  "Jun-8" 
[243] "Jun-9"  "Mar-1"  "Mar-10" "Mar-11" "Mar-12" "Mar-13" "Mar-14" "Mar-15" "Mar-16" "Mar-17" "Mar-18"
[254] "Mar-19" "Mar-2"  "Mar-20" "Mar-21" "Mar-22" "Mar-23" "Mar-24" "Mar-25" "Mar-26" "Mar-27" "Mar-28"
[265] "Mar-29" "Mar-3"  "Mar-30" "Mar-31" "Mar-4"  "Mar-5"  "Mar-6"  "Mar-7"  "Mar-8"  "Mar-9"  "May-1" 
[276] "May-10" "May-11" "May-12" "May-13" "May-14" "May-15" "May-16" "May-17" "May-18" "May-19" "May-2" 
[287] "May-20" "May-21" "May-22" "May-23" "May-24" "May-25" "May-26" "May-27" "May-28" "May-29" "May-3" 
[298] "May-30" "May-31" "May-4"  "May-5"  "May-6"  "May-7"  "May-8"  "May-9"  "Oct-1"  "Oct-10" "Oct-11"
[309] "Oct-12" "Oct-13" "Oct-14" "Oct-15" "Oct-16" "Oct-17" "Oct-18" "Oct-19" "Oct-2"  "Oct-20" "Oct-21"
[320] "Oct-22" "Oct-23" "Oct-24" "Oct-25" "Oct-26" "Oct-27" "Oct-28" "Oct-29" "Oct-3"  "Oct-30" "Oct-31"
[331] "Oct-4"  "Oct-5"  "Oct-6"  "Oct-7"  "Oct-8"  "Oct-9"  "Sep-1"  "Sep-10" "Sep-11" "Sep-12" "Sep-13"
[342] "Sep-14" "Sep-15" "Sep-16" "Sep-17" "Sep-18" "Sep-19" "Sep-2"  "Sep-20" "Sep-21" "Sep-22" "Sep-23"
[353] "Sep-24" "Sep-25" "Sep-26" "Sep-27" "Sep-28" "Sep-29" "Sep-3"  "Sep-30" "Sep-4"  "Sep-5"  "Sep-6" 
[364] "Sep-7"  "Sep-8"  "Sep-9" 

Summer 2021-2022

This includes the data from the 1-Nov 2021 to the 15 of Feb 2022.

* I only have the data until the 3rd of Feb yet

summer_21_22 <- data_clean %>% 
  filter(Year == 2021 & Month %in% c(11,12) |  # Filter all data points in Nov, Dec 2021 and Jan, Feb 2022
           Year == 2022 & Month %in% c(1,2)) %>% 
  filter(!(Month == 2 & Day > 15))  # remove days over the 15th of Feb

# Check our data

head(summer_21_22)  # First 6 rows 
tail(summer_21_22)  # Last 6 rows

summer_21_22$Date_Combined <- reorder(summer_21_22$Date_Combined, summer_21_22$Day_cum)  # reorder the factors of Date_Combined according to the values of Day_cum. Do it for each subset individually because factors repeat for each year

levels(summer_21_22$Date_Combined)
  [1] "Nov-1"  "Nov-2"  "Nov-3"  "Nov-4"  "Nov-5"  "Nov-6"  "Nov-7"  "Nov-8"  "Nov-9"  "Nov-10" "Nov-11"
 [12] "Nov-12" "Nov-13" "Nov-14" "Nov-15" "Nov-16" "Nov-17" "Nov-18" "Nov-19" "Nov-20" "Nov-21" "Nov-22"
 [23] "Nov-23" "Nov-24" "Nov-25" "Nov-26" "Nov-27" "Nov-28" "Nov-29" "Nov-30" "Dec-1"  "Dec-2"  "Dec-3" 
 [34] "Dec-4"  "Dec-5"  "Dec-6"  "Dec-7"  "Dec-8"  "Dec-9"  "Dec-10" "Dec-11" "Dec-12" "Dec-13" "Dec-14"
 [45] "Dec-15" "Dec-16" "Dec-17" "Dec-18" "Dec-19" "Dec-20" "Dec-21" "Dec-22" "Dec-23" "Dec-24" "Dec-25"
 [56] "Dec-26" "Dec-27" "Dec-28" "Dec-29" "Dec-30" "Dec-31" "Jan-1"  "Jan-2"  "Jan-3"  "Jan-4"  "Jan-5" 
 [67] "Jan-6"  "Jan-7"  "Jan-8"  "Jan-9"  "Jan-10" "Jan-11" "Jan-12" "Jan-13" "Jan-14" "Jan-15" "Jan-16"
 [78] "Jan-17" "Jan-18" "Jan-19" "Jan-20" "Jan-21" "Jan-22" "Jan-23" "Jan-24" "Jan-25" "Jan-26" "Jan-27"
 [89] "Jan-28" "Jan-29" "Jan-30" "Jan-31" "Feb-1"  "Feb-2"  "Feb-3"  "Apr-1"  "Apr-10" "Apr-11" "Apr-12"
[100] "Apr-13" "Apr-14" "Apr-15" "Apr-16" "Apr-17" "Apr-18" "Apr-19" "Apr-2"  "Apr-20" "Apr-21" "Apr-22"
[111] "Apr-23" "Apr-24" "Apr-25" "Apr-26" "Apr-27" "Apr-28" "Apr-29" "Apr-3"  "Apr-30" "Apr-4"  "Apr-5" 
[122] "Apr-6"  "Apr-7"  "Apr-8"  "Apr-9"  "Aug-1"  "Aug-10" "Aug-11" "Aug-12" "Aug-13" "Aug-14" "Aug-15"
[133] "Aug-16" "Aug-17" "Aug-18" "Aug-19" "Aug-2"  "Aug-20" "Aug-21" "Aug-22" "Aug-23" "Aug-24" "Aug-25"
[144] "Aug-26" "Aug-27" "Aug-28" "Aug-29" "Aug-3"  "Aug-30" "Aug-31" "Aug-4"  "Aug-5"  "Aug-6"  "Aug-7" 
[155] "Aug-8"  "Aug-9"  "Feb-10" "Feb-11" "Feb-12" "Feb-13" "Feb-14" "Feb-15" "Feb-16" "Feb-17" "Feb-18"
[166] "Feb-19" "Feb-20" "Feb-21" "Feb-22" "Feb-23" "Feb-24" "Feb-25" "Feb-26" "Feb-27" "Feb-28" "Feb-29"
[177] "Feb-4"  "Feb-5"  "Feb-6"  "Feb-7"  "Feb-8"  "Feb-9"  "Jul-1"  "Jul-10" "Jul-11" "Jul-12" "Jul-13"
[188] "Jul-14" "Jul-15" "Jul-16" "Jul-17" "Jul-18" "Jul-19" "Jul-2"  "Jul-20" "Jul-21" "Jul-22" "Jul-23"
[199] "Jul-24" "Jul-25" "Jul-26" "Jul-27" "Jul-28" "Jul-29" "Jul-3"  "Jul-30" "Jul-31" "Jul-4"  "Jul-5" 
[210] "Jul-6"  "Jul-7"  "Jul-8"  "Jul-9"  "Jun-1"  "Jun-10" "Jun-11" "Jun-12" "Jun-13" "Jun-14" "Jun-15"
[221] "Jun-16" "Jun-17" "Jun-18" "Jun-19" "Jun-2"  "Jun-20" "Jun-21" "Jun-22" "Jun-23" "Jun-24" "Jun-25"
[232] "Jun-26" "Jun-27" "Jun-28" "Jun-29" "Jun-3"  "Jun-30" "Jun-4"  "Jun-5"  "Jun-6"  "Jun-7"  "Jun-8" 
[243] "Jun-9"  "Mar-1"  "Mar-10" "Mar-11" "Mar-12" "Mar-13" "Mar-14" "Mar-15" "Mar-16" "Mar-17" "Mar-18"
[254] "Mar-19" "Mar-2"  "Mar-20" "Mar-21" "Mar-22" "Mar-23" "Mar-24" "Mar-25" "Mar-26" "Mar-27" "Mar-28"
[265] "Mar-29" "Mar-3"  "Mar-30" "Mar-31" "Mar-4"  "Mar-5"  "Mar-6"  "Mar-7"  "Mar-8"  "Mar-9"  "May-1" 
[276] "May-10" "May-11" "May-12" "May-13" "May-14" "May-15" "May-16" "May-17" "May-18" "May-19" "May-2" 
[287] "May-20" "May-21" "May-22" "May-23" "May-24" "May-25" "May-26" "May-27" "May-28" "May-29" "May-3" 
[298] "May-30" "May-31" "May-4"  "May-5"  "May-6"  "May-7"  "May-8"  "May-9"  "Oct-1"  "Oct-10" "Oct-11"
[309] "Oct-12" "Oct-13" "Oct-14" "Oct-15" "Oct-16" "Oct-17" "Oct-18" "Oct-19" "Oct-2"  "Oct-20" "Oct-21"
[320] "Oct-22" "Oct-23" "Oct-24" "Oct-25" "Oct-26" "Oct-27" "Oct-28" "Oct-29" "Oct-3"  "Oct-30" "Oct-31"
[331] "Oct-4"  "Oct-5"  "Oct-6"  "Oct-7"  "Oct-8"  "Oct-9"  "Sep-1"  "Sep-10" "Sep-11" "Sep-12" "Sep-13"
[342] "Sep-14" "Sep-15" "Sep-16" "Sep-17" "Sep-18" "Sep-19" "Sep-2"  "Sep-20" "Sep-21" "Sep-22" "Sep-23"
[353] "Sep-24" "Sep-25" "Sep-26" "Sep-27" "Sep-28" "Sep-29" "Sep-3"  "Sep-30" "Sep-4"  "Sep-5"  "Sep-6" 
[364] "Sep-7"  "Sep-8"  "Sep-9" 

Make plots for PAR and Temperature in each summer, in each sample

  1. Summer 2019-2020

Sample X1 (moss)


(temp_plot_19_20_X1 <- summer_19_20 %>% 
   ggplot(aes(Date_Combined, X1.Temp)) +
   geom_point()+  # Add points for the data
   geom_line()+  # Add a line that joins the points
   geom_hline(yintercept = 0, color = "blue", linetype = "dashed") +
   labs(x = "\nDate (day)", y = "Temperature \nMoss X1 (°C)") +
   theme_graphs_env_cond() +
    theme(axis.text.x = element_blank(),
        axis.title.x = element_blank()))  # Remove axis label and text for the graph


(PAR_plot_19_20_X1 <-summer_19_20 %>% 
    ggplot(aes(Date_Combined, X1.PAR)) +
   geom_point()+  # Add points for the data
   geom_line()+  # add a line that joins the points
   labs(x = "\nDate (day)", y = "PAR \n(µmol m-2 s^-1)") +
   theme_graphs_env_cond())


(combined_plot_19_20_X1 <- (temp_plot_19_20_X1/PAR_plot_19_20_X1) & plot_layout(ncol = 1))

Sample X2 (moss)

(temp_plot_19_20_X2 <- summer_19_20 %>% 
   ggplot(aes(Date_Combined, X2.Temp)) +
   geom_point()+  # Add points for the data
   geom_line()+  # add a line that joins the points
   geom_hline(yintercept = 0, color = "blue", linetype = "dashed") +
   labs(x = "\nDate (day)", y = "Temperature \nMoss X2 (°C)") +
   theme_graphs_env_cond()+
   theme(axis.text.x = element_blank(),
        axis.title.x = element_blank()))


(PAR_plot_19_20_X2 <-summer_19_20 %>% 
    ggplot(aes(Date_Combined, X2.PAR)) +
   geom_point()+  # Add points for the data
   geom_line()+  # add a line that joins the points
   labs(x = "\nDate (day)", y = "PAR \n(µmol m-2 s^-1)") +
   theme_graphs_env_cond())

  
(combined_plot_19_20_X2 <- (temp_plot_19_20_X2/PAR_plot_19_20_X2) & plot_layout(ncol = 1))

Sample X3 (Lichen)

(temp_plot_19_20_X3 <- summer_19_20 %>% 
   ggplot(aes(Date_Combined, X3.Temp)) +
   geom_point()+  # Add points for the data
   geom_line()+  # add a line that joins the points
   geom_hline(yintercept = 0, color = "blue", linetype = "dashed") +
   labs(x = "\nDate (day)", y = "Temperature \nLichen X3 (°C)") +
   theme_graphs_env_cond()+
   theme(axis.text.x = element_blank(),
        axis.title.x = element_blank()))


(PAR_plot_19_20_X3 <-summer_19_20 %>% 
    ggplot(aes(Date_Combined, X3.PAR)) +
   geom_point()+  # Add points for the data
   geom_line()+  # add a line that joins the points
   labs(x = "\nDate (day)", y = "PAR \n(µmol m-2 s^-1)") +
   theme_graphs_env_cond())

  
(combined_plot_19_20_X3 <- (temp_plot_19_20_X3/PAR_plot_19_20_X3) & plot_layout(ncol = 1)) 

Sample X4 (Moss)

(temp_plot_19_20_X4 <- summer_19_20 %>% 
   ggplot(aes(Date_Combined, X4.Temp)) +
   geom_point()+  # Add points for the data
   geom_line()+  # add a line that joins the points
   geom_hline(yintercept = 0, color = "blue", linetype = "dashed") +
   labs(x = "\nDate (day)", y = "Temperature \nMoss X4 (°C)") +
   theme_graphs_env_cond()+
   theme(axis.text.x = element_blank(),
        axis.title.x = element_blank()))


(PAR_plot_19_20_X4 <-summer_19_20 %>% 
    ggplot(aes(Date_Combined, X4.PAR)) +
   geom_point()+  # Add points for the data
   geom_line()+  # add a line that joins the points
   labs(x = "\nDate (day)", y = "PAR \n(µmol m-2 s^-1)") +
   theme_graphs_env_cond())

  
(combined_plot_19_20_X4 <- (temp_plot_19_20_X4/PAR_plot_19_20_X4) & plot_layout(ncol = 1)) 

NA
NA
  1. Summer 2020-2021

Sample X1 (Moss)

(temp_plot_20_21_X1 <- summer_20_21 %>% 
   ggplot(aes(Date_Combined, X1.Temp)) +
   geom_point()+  # Add points for the data
   geom_line()+  # Add a line that joins the points
   geom_hline(yintercept = 0, color = "blue", linetype = "dashed") +
   labs(x = "\nDate (day)", y = "Temperature \nMoss X1 (°C)") +
   theme_graphs_env_cond() +
    theme(axis.text.x = element_blank(),
        axis.title.x = element_blank()))  # Remove axis label and text for the graph


(PAR_plot_20_21_X1 <-summer_20_21 %>% 
    ggplot(aes(Date_Combined, X1.PAR)) +
   geom_point()+  # Add points for the data
   geom_line()+  # add a line that joins the points
   labs(x = "\nDate (day)", y = "PAR \n(µmol m-2 s^-1)") +
   theme_graphs_env_cond())


(combined_plot_20_21_X1 <- (temp_plot_20_21_X1/PAR_plot_20_21_X1) & plot_layout(ncol = 1))

Sample X2 (Moss)

(temp_plot_20_21_X2 <- summer_20_21 %>% 
   ggplot(aes(Date_Combined, X2.Temp)) +
   geom_point()+  # Add points for the data
   geom_line()+  # Add a line that joins the points
   geom_hline(yintercept = 0, color = "blue", linetype = "dashed") +
   labs(x = "\nDate (day)", y = "Temperature \nMoss X1 (°C)") +
   theme_graphs_env_cond() +
    theme(axis.text.x = element_blank(),
        axis.title.x = element_blank()))  # Remove axis label and text for the graph


(PAR_plot_20_21_X2 <-summer_20_21 %>% 
    ggplot(aes(Date_Combined, X2.PAR)) +
   geom_point()+  # Add points for the data
   geom_line()+  # add a line that joins the points
   labs(x = "\nDate (day)", y = "PAR \n(µmol m-2 s^-1)") +
   theme_graphs_env_cond())


(combined_plot_20_21_X2 <- (temp_plot_20_21_X2/PAR_plot_20_21_X2) & plot_layout(ncol = 1))

Saple X3 (Lichen)

(temp_plot_20_21_X3 <- summer_20_21 %>% 
   ggplot(aes(Date_Combined, X3.Temp)) +
   geom_point()+  # Add points for the data
   geom_line()+  # Add a line that joins the points
   geom_hline(yintercept = 0, color = "blue", linetype = "dashed") +
   labs(x = "\nDate (day)", y = "Temperature \nMoss X1 (°C)") +
   theme_graphs_env_cond() +
    theme(axis.text.x = element_blank(),
        axis.title.x = element_blank()))  # Remove axis label and text for the graph


(PAR_plot_20_21_X3 <-summer_20_21 %>% 
    ggplot(aes(Date_Combined, X3.PAR)) +
   geom_point()+  # Add points for the data
   geom_line()+  # add a line that joins the points
   labs(x = "\nDate (day)", y = "PAR \n(µmol m-2 s^-1)") +
   theme_graphs_env_cond())


(combined_plot_20_21_X3 <- (temp_plot_20_21_X3/PAR_plot_20_21_X3) & plot_layout(ncol = 1))

LS0tCnRpdGxlOiAiUiBOb3RlYm9vayIKb3V0cHV0OiBodG1sX25vdGVib29rCi0tLQoKMS4gIFNldCB3b3JraW5nIGRpcmVjdG9yeQoKYGBge3J9CnNldHdkKCJ+L0xpYnJhcnkvQ2xvdWRTdG9yYWdlL09uZURyaXZlLVVuaXZlcnNpdHlvZkVkaW5idXJnaC80dGggeWVhci9kaXNzZXJ0YXRpb24vZGlzc2VydGF0aW9uIikKYGBgCgoyLiAgTG9hZCBwYWNrYWdlcwoKYGBge3IsIG1lc3NhZ2U9RkFMU0V9CmxpYnJhcnkoc2tpbXIpICAjIHN1bW1hcnkKbGlicmFyeSh0aWR5dmVyc2UpCmxpYnJhcnkobHVicmlkYXRlKSAgIyBkYXRlcyBtYW5hZ2VtZW50CmxpYnJhcnkoZ3JpZEV4dHJhKSAgIyBhcnJhbmdlIHBsb3RzCmxpYnJhcnkocGF0Y2h3b3JrKSAgIyBjb21iaW5lIHBsb3RzCmBgYAoyLjIuIENyZWF0ZXMgZnVuY3Rpb25zCgotIEZ1bmN0aW9uIGZvciBncmFwaCBhc3RoZXRpY3MKCmBgYHtyLCBlY2hvPSBUUlVFLCByZXN1bHRzPSJoaWRlIn0KdGhlbWVfZ3JhcGhzX2Vudl9jb25kIDwtIGZ1bmN0aW9uKCl7CiAgdGhlbWVfY2xhc3NpYygpICsKICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDkwKSkrCiAgIHRoZW1lKGF4aXMudGV4dCA9IGVsZW1lbnRfdGV4dChzaXplID0gMTEpLCAgIyBBZGp1c3QgdGhlIHNpemUgYXMgbmVlZGVkCiAgICAgICAgICBheGlzLnRpdGxlID0gZWxlbWVudF90ZXh0KHNpemUgPSAxOCksCiAgICAgICAgbGVnZW5kLnRleHQgPSBlbGVtZW50X3RleHQoc2l6ZT0xNCkpCiAgfQpgYGAKCjMuICBMb2FkIHRoZSBkYXRhIGFuZCBzZWUgaXRzIHN0cnVjdHVyZQoKYGBge3J9CmRhdGEgPC0gcmVhZC5jc3YoIkRhdGFfUEFNX1Njb3R0X0Jhc2UuY3N2IikgIyBsb2FkIGRhdGEKc2tpbXI6OnNraW0oZGF0YSkgICMgc2VlIGEgc3VtbWFyeSBvZiB0aGUgd2hvbGUgZGF0YQpzdHIoZGF0YSkgICMgc2VlIHRoZSBzdHJ1Y3R1cmUgb2YgZWFjaCB2YXJpYWJsZQp0YWlsKGRhdGEpICAjIHZpZXcgdGhlIGxhc3QgNiByb3dzIG9mIGRhdGEKaGVhZChkYXRhKSAgIyB2aWV3IHRoZSBmaXJzdCA2IHJvd3Mgb2YgZGF0YQpgYGAKCkRhdGEgb2Ygc2Vuc29ycyAxLDIgYW5kIDQgYXJlIGZvciB0aGUgbW9zcyBhbmQgMyBpcyBmb3IgdGhlIGxpY2hlbi4gRGF0YSBpcyBmcm9tIEphbiAyMDE5IHRvIEZlYiAyMDIyLiBJIGFtIGdvaW5nIHRvIGNvbnNpZGVyIHN1bW1lciBmb3JtIDEgTm92IHRvIDE1IEZlYi4gSSBjdXJyZW50bHkgaGF2ZSBkYXRhIGZvciAzIHN1bW1lcnM6IDIwMTktMjAyMCwgMjAyMC0yMDIxLCAyMDIxLTIwMjIuCgojIyA0LiBGb3JtYXQgZGF0YSBpbiBhIHdheSB0aGF0IGlzIGdvaW5nIHRvIGJlIHVzZWZ1bCB0byBtZQoKNC4xLiBSZW1vdmUgd2VpcmQgdGltZXMgYW5kIGRhdGVzIGFuZCBkaXZpZGUgdGhlIHVzZWZ1bCBvbmVzCgpgYGB7cn0KZGF0YV9jbGVhbiA8LSBkYXRhWywgLWMoMjoxMyldICU+JSAgICMgY3JlYXRlIGEgbmV3IGRhdGEgc2V0IHdpdGhvdXQgY29sdW1ucyAyIHRvIDEzCiAgbXV0YXRlKERheV9jdW0gPSBhcy5udW1lcmljKGRhdGEkRGF0ZSkpICMgbWFpbnRhaW4gY3VtdWxhdGl2ZSBkYXRlIGJ1dCBjaGFuZ2UgY29sdW1uIG5hbWUgdG8gbW9yZSBpbmZvcm1hdGl2ZSBvbmUgYW5kIG1ha2UgaXQgbnVtZXJpYwoKZGF0YV9jbGVhbiA8LSBkYXRhX2NsZWFuICU+JSAKICBtdXRhdGUoRGF0ZSA9IHBhcnNlX2RhdGVfdGltZShEYXRldGltZSwgJ2RteSBITScpKSAgICMgaW5kaWNhdGUgdGhlIGZvcm1hdCB0aGUgZGF0ZSBpcyB3YW50ZWQKCnByaW50KGRhdGFfY2xlYW5baXMubmEoZGF0YV9jbGVhbiREYXRlKSwgXSkgICMgQ2hlY2sgZm9yIHJvd3Mgd2l0aCBwYXJzaW5nIGlzc3Vlc1wKIyAgUm93IDU4NCBpcyBwcm9ibGVtYXRpYwoKZGF0YV9jbGVhbls1ODQsIDFdPC0iMTAvMDIvMjAxOSAxMDowOCIgICMgQ2hhbmdlIHRoZSB2YWx1ZSB0byB0aGUgY29ycmVjdCBvbmUgCgpkYXRhX2NsZWFuIDwtIGRhdGFfY2xlYW4gJT4lIAogIG11dGF0ZShEYXRlID0gcGFyc2VfZGF0ZV90aW1lKERhdGV0aW1lLCAnZG15IEhNJykpICAgIyByZXBlYXQgd2l0aCBhbGwgdGhlIGxpbmVzIHdvcmtpbmcKCmRhdGFfY2xlYW4gPC0gZGF0YV9jbGVhbiAlPiUgICMgY3JlYXRlIG5ldyBjb2x1bW5zIHdpdGggbW9udGgsIHllYXIsCiAgbXV0YXRlKE1vbnRoID0gbW9udGgoRGF0ZSksICMgZGF5LCBtaW51dGUgICAgICAgICAgICAgICAgICAgICAKICAgICAgICAgWWVhciA9IHllYXIoRGF0ZSksCiAgICAgICAgIERheSA9IGRheShEYXRlKSwKICAgICAgICAgSG91ciA9IGhvdXIoRGF0ZSksIAogICAgICAgICBNaW51dGUgPSBtaW51dGUoRGF0ZSkpCgpkYXRhX2NsZWFuWzU4NCxdICAjIGNoZWNrIGl0IHdvcmtlZAoKYGBgCgo0LjIuIENoZWNrIHRoZSBuZXcgZGF0YQoKYGBge3IsIGVjaG89IFRSVUUsIHJlc3VsdHM9J2hpZGUnfQpzdHIoZGF0YV9jbGVhbikKc2tpbXI6OnNraW0oZGF0YV9jbGVhbikKYGBgCgo0LjMuIENoYW5nZSB0aGUgZGlmZiBjb2x1bW5zIG5hbWVzIHRvIG1hdGNoIHRoZSByZXN0IG9mIGNvbHVtbnMKCmBgYHtyfQoKZGF0YV9jbGVhbjwtZGF0YV9jbGVhbiAlPiUgCiAgcmVuYW1lKFgxLmRpZmYgPSBkaWZmLAogICAgICAgICBYMi5kaWZmID0gZGlmZi4xLAogICAgICAgICBYMy5kaWZmID0gZGlmZi4yLAogICAgICAgICBYNC5kaWZmID0gZGlmZi4zKQpgYGAKCjQuNC4gTmVlZCB0byBjaGFuZ2Ugc29tZSB2YXJpYWJsZXMgb2YgZm9ybWF0CgpgYGB7ciwgd2FybmluZyA9IEZBTFNFfQoKZGF0YV9jbGVhbiA8LSBkYXRhX2NsZWFuICU+JQogIG11dGF0ZShYMS5QQVIgPSBhcy5udW1lcmljKFgxLlBBUiksICAjIENoYW5nZSBQQVIgb2YgWDEsIFgyIGFuZCBYMyB0byBudW1lcmljCiAgICAgICAgIFgyLlBBUiA9IGFzLm51bWVyaWMoWDIuUEFSKSwgCiAgICAgICAgIFgzLlBBUiA9IGFzLm51bWVyaWMoWDMuUEFSKSwgCiAgICAgICAgIFg0LlBBUiA9IGFzLm51bWVyaWMoWDQuUEFSKSwKICAgICAgICAgWDMuRiA9IGFzLm51bWVyaWMoWDMuRiksICAjIENoYW5nZSBGIGFuZCBGbSB0byBudW1lcmljCiAgICAgICAgIFgzLkZtLiA9IGFzLm51bWVyaWMoWDMuRm0uKSwKICAgICAgICAgWDMuVGVtcCA9IGFzLm51bWVyaWMoWDMuVGVtcCksICAjIENoYW5nZSBUZW1wIDMgdG8gbnVtZXJpYwogICAgICAgICBYMS5kaWZmID0gYXMubnVtZXJpYyhYMS5kaWZmKSwgICMgQ2hhbmdlIGFsbCBkaWZmIHRvIG51bWVyaWMKICAgICAgICAgWDIuZGlmZiA9IGFzLm51bWVyaWMoWDIuZGlmZiksCiAgICAgICAgIFgzLmRpZmYgPSBhcy5udW1lcmljKFgzLmRpZmYpLAogICAgICAgICBYNC5kaWZmID0gYXMubnVtZXJpYyhYNC5kaWZmKSkKICAgICAgICAgI01vbnRoID0gYXMuZmFjdG9yKE1vbnRoKSwgICMgQ2hhbmdlIGRheSwgbW9udGggYW5kIHllYXIgdG8gY2F0ZWdvcmllcyAtPiBpcyBpdCBhIGdyZWF0IGlkZWE/CiAgICAgICAgICNZZWFyID0gYXMuZmFjdG9yKFllYXIpLCAKICAgICAgICAgI0RheSA9IGFzLmZhY3RvcihEYXkpKQpgYGAKCjQuNS4gQ3JlYXRlIGNvbHVtbiBmb3IgbW9udGggKGluIGxldHRlcnMpIGFuZCBkYXktbW9udGggCgpgYGB7cn0KZGF0YV9jbGVhbiA8LSBkYXRhX2NsZWFuICU+JSAKICBtdXRhdGUoTW9udGhfTmFtZSA9IGFzLmZhY3RvcihjYXNlX3doZW4oICAjIE1ha2UgYSBjb2x1bW4gd2l0aCB0aGUgbmFtZXMgb2YgdGhlIG1vbnRocyBhbmQgbWFrZSB0aGVtIGEgZmFjdG9yCiAgTW9udGggPT0gMSB+ICJKYW4iLCAgIyBjYXNlX3doZW4gZnJvbSBkcGx5ciBwYWNrYWdlCiAgTW9udGggPT0gMiB+ICJGZWIiLAogIE1vbnRoID09IDMgfiAiTWFyIiwKICBNb250aCA9PSA0IH4gIkFwciIsCiAgTW9udGggPT0gNSB+ICJNYXkiLAogIE1vbnRoID09IDYgfiAiSnVuIiwKICBNb250aCA9PSA3IH4gIkp1bCIsCiAgTW9udGggPT0gOCB+ICJBdWciLAogIE1vbnRoID09IDkgfiAiU2VwIiwKICBNb250aCA9PSAxMCB+ICJPY3QiLAogIE1vbnRoID09IDExIH4gIk5vdiIsCiAgTW9udGggPT0gMTIgfiAiRGVjIikpKSAlPiUgCiAgbXV0YXRlKERhdGVfQ29tYmluZWQgPSBhcy5mYWN0b3IoICAjIE1ha2UgYSBjb2x1bW4gd2l0aCB0aGUgZGF5IGFuZCBtb250aCBuYW1lIHNlcGFyYXRlZCBieSAtCiAgICBwYXN0ZShNb250aF9OYW1lLCBEYXksIHNlcCA9ICItIikpKSAgIyBNYWtlIHRoZSBjb2x1bW4gYSBmYWN0b3IKCmBgYAoKNC42LiBGaXggRGF5X2N1bQoKYGBge3J9CnByaW50KGRhdGFfY2xlYW5baXMubmEoZGF0YV9jbGVhbiREYXlfY3VtKSwgXSkgICMgQ2hlY2sgZm9yIHJvd3Mgd2l0aCBOQXMgaW4gRGF5X2N1bQoKIyBGcm9tIDI1LzAxLzIwMjIgdGhlIGRhdGUgZm9ybWF0IGNoYW5nZXMgYW5kIGl0IGlzIG5vdCBjdW1tdWxhdGl2ZSBhbnltb3JlCgpkYXRhX2NsZWFuIDwtIGRhdGFfY2xlYW4gJT4lCiAgbXV0YXRlKERhdGVfbm9fdGltZSA9IHBhc3RlKHllYXIoRGF0ZSksIG1vbnRoKERhdGUpLCBkYXkoRGF0ZSksIHNlcCA9ICItIikpICU+JSAgIyBDcmVhdGUgYWNvbHVtbiB3aXRoIHRoZSBkYXRlIGJ1dCB3aXRob3V0IHRoZSB0aW1lCiAgbXV0YXRlKERheV9jdW0gPSBpZl9lbHNlKE5vLiA+PSAyNjUxMCwgNDQ1ODYgKyBhcy5udW1lcmljKGRpZmZ0aW1lKERhdGVfbm9fdGltZSwgYXMuRGF0ZSgiMjAyMi0wMS0yNSIpLCB1bml0cyA9ICJkYXlzIikpLCBEYXlfY3VtKSkgJT4lICAjIEZpeCB0aGUgZm9ybWF0IG9mIERheV9jdW0gYWZ0ZXIgdGhlIDI1LzAxLzIwMjIKICAjIERpZmZ0aW1lIHdlZWtzIHRoZSB0aW1lIHBhc3NlZCBiZXR3ZWVuIDIgZGF5cyBpbiB0aGUgdW5pdHMgaW5kaWNhdGVkCiAgc2VsZWN0KC1EYXRlX25vX3RpbWUpICAjIFJlbW92ZSBEYXRlX25vX3RpbWUgZnJvbSB0aGUgZGF0YSBzZXQKICAKcHJpbnQoZGF0YV9jbGVhbltpcy5uYShkYXRhX2NsZWFuJERheV9jdW0pLCBdKSAgIyBDaGVjayBmb3Igcm93cyB3aXRoIE5BcyBpbiBEYXlfY3VtCgpoZWFkKGRhdGFfY2xlYW4kRGF0ZV9Db21iaW5lZCkgICMgQ2hlY2sgaXQgd29ya2VkCnRhaWwoZGF0YV9jbGVhbiREYXRlX0NvbWJpbmVkKQoKCmBgYAoKNC43LiBDcmVhdGUgYSBjb2x1bW4gZm9yIGF2ZXJhZ2UgbW9zcyB2YWx1ZXMgb2YgeWllbGQsUEFSLCBGLCBGbSwgVGVtcCwgRVRSIGFuZCBkaWZmCgpgYGB7cn0KZGF0YV9jbGVhbiA8LSBkYXRhX2NsZWFuICU+JSAKICBtdXRhdGUoYXZfbW9zc195aWVsZCA9IHJvd01lYW5zKGRhdGFfY2xlYW5bLCBjKCJYMS5ZLi5JSS4iLCAiWDIuWS4uSUkuIiwgIlg0LlkuLklJLiIpXSksICAjIHJvd01lYW5zIGdldHMgdGhlIG1lYW4gb2YgZWFjaCByb3cgaW4gdGhlIGRhdGEgZnJhbWUgYW5kIHN0b3JlcyB0aGUgcmVzdWx0IGluIGEgbmV3IGNvbHVtbgogICAgICAgICBhdl9tb3NzX1BBUiA9IHJvd01lYW5zKGRhdGFfY2xlYW5bLCBjKCJYMS5QQVIiLCAiWDIuUEFSIiwgIlg0LlBBUiIpXSksCiAgICAgICAgIGF2X21vc3NfRiA9IHJvd01lYW5zKGRhdGFfY2xlYW5bLCBjKCJYMS5GIiwgIlgyLkYiLCAiWDQuRiIpXSksCiAgICAgICAgIGF2X21vc3NfRm0gPSByb3dNZWFucyhkYXRhX2NsZWFuWywgYygiWDEuRm0uIiwgIlgyLkZtLiIsICJYNC5GbS4iKV0pLAogICAgICAgICBhdl9tb3NzX3RlbXAgPSByb3dNZWFucyhkYXRhX2NsZWFuWywgYygiWDEuVGVtcCIsICJYMi5UZW1wIiwgIlg0LlRlbXAiKV0pLAogICAgICAgICBhdl9tb3NzX0VUUiA9IHJvd01lYW5zKGRhdGFfY2xlYW5bLCBjKCJYMS5FVFIiLCAiWDIuRVRSIiwgIlg0LkVUUiIpXSksCiAgICAgICAgIGF2X21vc3NfZGlmZiA9IHJvd01lYW5zKGRhdGFfY2xlYW5bLCBjKCJYMS5kaWZmIiwgIlgyLmRpZmYiLCAiWDQuZGlmZiIpXSkpCmBgYAoKIyMgNS4gU3Vic2V0IGRhdGEgZm9yIHN1bW1lcnMgMjAxOS0yMDIwLCAyMDIwLTIwMjEsIDIwMjEtMjAyMgoKKipTdW1tZXIgMjAxOS0yMDIwKioKClRoaXMgaW5jbHVkZXMgdGhlIGRhdGEgZnJvbSB0aGUgMS1Ob3YgMjAxOSB0byB0aGUgMTUgb2YgRmViIDIwMjAKCmBgYHtyfQpzdW1tZXJfMTlfMjAgPC0gZGF0YV9jbGVhbiAlPiUgCiAgZmlsdGVyKFllYXIgPT0gMjAxOSAmIE1vbnRoICVpbiUgYygxMSwxMikgfCAgIyBGaWx0ZXIgYWxsIGRhdGEgcG9pbnRzIGluIE5vdiwgRGVjIDIwMTkgYW5kIEphbiwgRmViIDIwMjAKICAgICAgICAgICBZZWFyID09IDIwMjAgJiBNb250aCAlaW4lIGMoMSwyKSkgJT4lIAogIGZpbHRlcighKE1vbnRoID09IDIgJiBEYXkgPiAxNSkpICAjIHJlbW92ZSBkYXlzIG92ZXIgdGhlIDE1dGggb2YgRmViCgojIENoZWNrIG91ciBkYXRhCgpoZWFkKHN1bW1lcl8xOV8yMCkgICMgRmlyc3QgNiByb3dzIAp0YWlsKHN1bW1lcl8xOV8yMCkgICMgTGFzdCA2IHJvd3MKCnN1bW1lcl8xOV8yMCREYXRlX0NvbWJpbmVkIDwtIHJlb3JkZXIoc3VtbWVyXzE5XzIwJERhdGVfQ29tYmluZWQsIHN1bW1lcl8xOV8yMCREYXlfY3VtKSAgIyByZW9yZGVyIHRoZSBmYWN0b3JzIG9mIERhdGVfQ29tYmluZWQgYWNjb3JkaW5nIHRvIHRoZSB2YWx1ZXMgb2YgRGF5X2N1bS4gRG8gaXQgZm9yIGVhY2ggc3Vic2V0IGluZGl2aWR1YWxseSBiZWNhdXNlIGZhY3RvcnMgcmVwZWF0IGZvciBlYWNoIHllYXIKCmxldmVscyhzdW1tZXJfMTlfMjAkRGF0ZV9Db21iaW5lZCkKYGBgCgoqKlN1bW1lciAyMDIwLTIwMjEqKgoKVGhpcyBpbmNsdWRlcyB0aGUgZGF0YSBmcm9tIHRoZSAxLU5vdiAyMDIwIHRvIHRoZSAxNSBvZiBGZWIgMjAyMQoKYGBge3J9CnN1bW1lcl8yMF8yMSA8LSBkYXRhX2NsZWFuICU+JSAKICBmaWx0ZXIoWWVhciA9PSAyMDIwICYgTW9udGggJWluJSBjKDExLDEyKSB8ICAjIEZpbHRlciBhbGwgZGF0YSBwb2ludHMgaW4gTm92LCBEZWMgMjAyOSBhbmQgSmFuLCBGZWIgMjAyMQogICAgICAgICAgIFllYXIgPT0gMjAyMSAmIE1vbnRoICVpbiUgYygxLDIpKSAlPiUgCiAgZmlsdGVyKCEoTW9udGggPT0gMiAmIERheSA+IDE1KSkgICMgcmVtb3ZlIGRheXMgb3ZlciB0aGUgMTV0aCBvZiBGZWIKCiMgQ2hlY2sgb3VyIGRhdGEKCmhlYWQoc3VtbWVyXzIwXzIxKSAgIyBGaXJzdCA2IHJvd3MgCnRhaWwoc3VtbWVyXzIwXzIxKSAgIyBMYXN0IDYgcm93cwoKc3VtbWVyXzIwXzIxJERhdGVfQ29tYmluZWQgPC0gcmVvcmRlcihzdW1tZXJfMjBfMjEkRGF0ZV9Db21iaW5lZCwgc3VtbWVyXzIwXzIxJERheV9jdW0pICAjIHJlb3JkZXIgdGhlIGZhY3RvcnMgb2YgRGF0ZV9Db21iaW5lZCBhY2NvcmRpbmcgdG8gdGhlIHZhbHVlcyBvZiBEYXlfY3VtLiBEbyBpdCBmb3IgZWFjaCBzdWJzZXQgaW5kaXZpZHVhbGx5IGJlY2F1c2UgZmFjdG9ycyByZXBlYXQgZm9yIGVhY2ggeWVhcgoKbGV2ZWxzKHN1bW1lcl8yMF8yMSREYXRlX0NvbWJpbmVkKQpgYGAKCioqU3VtbWVyIDIwMjEtMjAyMioqCgpUaGlzIGluY2x1ZGVzIHRoZSBkYXRhIGZyb20gdGhlIDEtTm92IDIwMjEgdG8gdGhlIDE1IG9mIEZlYiAyMDIyLgoKXCogSSBvbmx5IGhhdmUgdGhlIGRhdGEgdW50aWwgdGhlIDNyZCBvZiBGZWIgeWV0CgpgYGB7cn0Kc3VtbWVyXzIxXzIyIDwtIGRhdGFfY2xlYW4gJT4lIAogIGZpbHRlcihZZWFyID09IDIwMjEgJiBNb250aCAlaW4lIGMoMTEsMTIpIHwgICMgRmlsdGVyIGFsbCBkYXRhIHBvaW50cyBpbiBOb3YsIERlYyAyMDIxIGFuZCBKYW4sIEZlYiAyMDIyCiAgICAgICAgICAgWWVhciA9PSAyMDIyICYgTW9udGggJWluJSBjKDEsMikpICU+JSAKICBmaWx0ZXIoIShNb250aCA9PSAyICYgRGF5ID4gMTUpKSAgIyByZW1vdmUgZGF5cyBvdmVyIHRoZSAxNXRoIG9mIEZlYgoKIyBDaGVjayBvdXIgZGF0YQoKaGVhZChzdW1tZXJfMjFfMjIpICAjIEZpcnN0IDYgcm93cyAKdGFpbChzdW1tZXJfMjFfMjIpICAjIExhc3QgNiByb3dzCgpzdW1tZXJfMjFfMjIkRGF0ZV9Db21iaW5lZCA8LSByZW9yZGVyKHN1bW1lcl8yMV8yMiREYXRlX0NvbWJpbmVkLCBzdW1tZXJfMjFfMjIkRGF5X2N1bSkgICMgcmVvcmRlciB0aGUgZmFjdG9ycyBvZiBEYXRlX0NvbWJpbmVkIGFjY29yZGluZyB0byB0aGUgdmFsdWVzIG9mIERheV9jdW0uIERvIGl0IGZvciBlYWNoIHN1YnNldCBpbmRpdmlkdWFsbHkgYmVjYXVzZSBmYWN0b3JzIHJlcGVhdCBmb3IgZWFjaCB5ZWFyCgpsZXZlbHMoc3VtbWVyXzIxXzIyJERhdGVfQ29tYmluZWQpCmBgYAoKIyMgTWFrZSBwbG90cyBmb3IgUEFSIGFuZCBUZW1wZXJhdHVyZSBpbiBlYWNoIHN1bW1lciwgaW4gZWFjaCBzYW1wbGUKCjEuIFN1bW1lciAyMDE5LTIwMjAKClNhbXBsZSBYMSAobW9zcykKCmBgYHtyfQoKKHRlbXBfcGxvdF8xOV8yMF9YMSA8LSBzdW1tZXJfMTlfMjAgJT4lIAogICBnZ3Bsb3QoYWVzKERhdGVfQ29tYmluZWQsIFgxLlRlbXApKSArCiAgIGdlb21fcG9pbnQoKSsgICMgQWRkIHBvaW50cyBmb3IgdGhlIGRhdGEKICAgZ2VvbV9saW5lKCkrICAjIEFkZCBhIGxpbmUgdGhhdCBqb2lucyB0aGUgcG9pbnRzCiAgIGdlb21faGxpbmUoeWludGVyY2VwdCA9IDAsIGNvbG9yID0gImJsdWUiLCBsaW5ldHlwZSA9ICJkYXNoZWQiKSArCiAgIGxhYnMoeCA9ICJcbkRhdGUgKGRheSkiLCB5ID0gIlRlbXBlcmF0dXJlIFxuTW9zcyBYMSAowrBDKSIpICsKICAgdGhlbWVfZ3JhcGhzX2Vudl9jb25kKCkgKwogICAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X2JsYW5rKCksCiAgICAgICAgYXhpcy50aXRsZS54ID0gZWxlbWVudF9ibGFuaygpKSkgICMgUmVtb3ZlIGF4aXMgbGFiZWwgYW5kIHRleHQgZm9yIHRoZSBncmFwaAoKKFBBUl9wbG90XzE5XzIwX1gxIDwtc3VtbWVyXzE5XzIwICU+JSAKICAgIGdncGxvdChhZXMoRGF0ZV9Db21iaW5lZCwgWDEuUEFSKSkgKwogICBnZW9tX3BvaW50KCkrICAjIEFkZCBwb2ludHMgZm9yIHRoZSBkYXRhCiAgIGdlb21fbGluZSgpKyAgIyBhZGQgYSBsaW5lIHRoYXQgam9pbnMgdGhlIHBvaW50cwogICBsYWJzKHggPSAiXG5EYXRlIChkYXkpIiwgeSA9ICJQQVIgXG4owrVtb2wgbS0yIHNeLTEpIikgKwogICB0aGVtZV9ncmFwaHNfZW52X2NvbmQoKSkKCihjb21iaW5lZF9wbG90XzE5XzIwX1gxIDwtICh0ZW1wX3Bsb3RfMTlfMjBfWDEvUEFSX3Bsb3RfMTlfMjBfWDEpICYgcGxvdF9sYXlvdXQobmNvbCA9IDEpKQoKYGBgCgpTYW1wbGUgWDIgKG1vc3MpCgpgYGB7cn0KKHRlbXBfcGxvdF8xOV8yMF9YMiA8LSBzdW1tZXJfMTlfMjAgJT4lIAogICBnZ3Bsb3QoYWVzKERhdGVfQ29tYmluZWQsIFgyLlRlbXApKSArCiAgIGdlb21fcG9pbnQoKSsgICMgQWRkIHBvaW50cyBmb3IgdGhlIGRhdGEKICAgZ2VvbV9saW5lKCkrICAjIGFkZCBhIGxpbmUgdGhhdCBqb2lucyB0aGUgcG9pbnRzCiAgIGdlb21faGxpbmUoeWludGVyY2VwdCA9IDAsIGNvbG9yID0gImJsdWUiLCBsaW5ldHlwZSA9ICJkYXNoZWQiKSArCiAgIGxhYnMoeCA9ICJcbkRhdGUgKGRheSkiLCB5ID0gIlRlbXBlcmF0dXJlIFxuTW9zcyBYMiAowrBDKSIpICsKICAgdGhlbWVfZ3JhcGhzX2Vudl9jb25kKCkrCiAgIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF9ibGFuaygpLAogICAgICAgIGF4aXMudGl0bGUueCA9IGVsZW1lbnRfYmxhbmsoKSkpCgooUEFSX3Bsb3RfMTlfMjBfWDIgPC1zdW1tZXJfMTlfMjAgJT4lIAogICAgZ2dwbG90KGFlcyhEYXRlX0NvbWJpbmVkLCBYMi5QQVIpKSArCiAgIGdlb21fcG9pbnQoKSsgICMgQWRkIHBvaW50cyBmb3IgdGhlIGRhdGEKICAgZ2VvbV9saW5lKCkrICAjIGFkZCBhIGxpbmUgdGhhdCBqb2lucyB0aGUgcG9pbnRzCiAgIGxhYnMoeCA9ICJcbkRhdGUgKGRheSkiLCB5ID0gIlBBUiBcbijCtW1vbCBtLTIgc14tMSkiKSArCiAgIHRoZW1lX2dyYXBoc19lbnZfY29uZCgpKQogIAooY29tYmluZWRfcGxvdF8xOV8yMF9YMiA8LSAodGVtcF9wbG90XzE5XzIwX1gyL1BBUl9wbG90XzE5XzIwX1gyKSAmIHBsb3RfbGF5b3V0KG5jb2wgPSAxKSkKCmBgYAoKU2FtcGxlIFgzIChMaWNoZW4pCgpgYGB7cn0KKHRlbXBfcGxvdF8xOV8yMF9YMyA8LSBzdW1tZXJfMTlfMjAgJT4lIAogICBnZ3Bsb3QoYWVzKERhdGVfQ29tYmluZWQsIFgzLlRlbXApKSArCiAgIGdlb21fcG9pbnQoKSsgICMgQWRkIHBvaW50cyBmb3IgdGhlIGRhdGEKICAgZ2VvbV9saW5lKCkrICAjIGFkZCBhIGxpbmUgdGhhdCBqb2lucyB0aGUgcG9pbnRzCiAgIGdlb21faGxpbmUoeWludGVyY2VwdCA9IDAsIGNvbG9yID0gImJsdWUiLCBsaW5ldHlwZSA9ICJkYXNoZWQiKSArCiAgIGxhYnMoeCA9ICJcbkRhdGUgKGRheSkiLCB5ID0gIlRlbXBlcmF0dXJlIFxuTGljaGVuIFgzICjCsEMpIikgKwogICB0aGVtZV9ncmFwaHNfZW52X2NvbmQoKSsKICAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X2JsYW5rKCksCiAgICAgICAgYXhpcy50aXRsZS54ID0gZWxlbWVudF9ibGFuaygpKSkKCihQQVJfcGxvdF8xOV8yMF9YMyA8LXN1bW1lcl8xOV8yMCAlPiUgCiAgICBnZ3Bsb3QoYWVzKERhdGVfQ29tYmluZWQsIFgzLlBBUikpICsKICAgZ2VvbV9wb2ludCgpKyAgIyBBZGQgcG9pbnRzIGZvciB0aGUgZGF0YQogICBnZW9tX2xpbmUoKSsgICMgYWRkIGEgbGluZSB0aGF0IGpvaW5zIHRoZSBwb2ludHMKICAgbGFicyh4ID0gIlxuRGF0ZSAoZGF5KSIsIHkgPSAiUEFSIFxuKMK1bW9sIG0tMiBzXi0xKSIpICsKICAgdGhlbWVfZ3JhcGhzX2Vudl9jb25kKCkpCiAgCihjb21iaW5lZF9wbG90XzE5XzIwX1gzIDwtICh0ZW1wX3Bsb3RfMTlfMjBfWDMvUEFSX3Bsb3RfMTlfMjBfWDMpICYgcGxvdF9sYXlvdXQobmNvbCA9IDEpKSAKCmBgYAoKU2FtcGxlIFg0IChNb3NzKQoKYGBge3J9Cih0ZW1wX3Bsb3RfMTlfMjBfWDQgPC0gc3VtbWVyXzE5XzIwICU+JSAKICAgZ2dwbG90KGFlcyhEYXRlX0NvbWJpbmVkLCBYNC5UZW1wKSkgKwogICBnZW9tX3BvaW50KCkrICAjIEFkZCBwb2ludHMgZm9yIHRoZSBkYXRhCiAgIGdlb21fbGluZSgpKyAgIyBhZGQgYSBsaW5lIHRoYXQgam9pbnMgdGhlIHBvaW50cwogICBnZW9tX2hsaW5lKHlpbnRlcmNlcHQgPSAwLCBjb2xvciA9ICJibHVlIiwgbGluZXR5cGUgPSAiZGFzaGVkIikgKwogICBsYWJzKHggPSAiXG5EYXRlIChkYXkpIiwgeSA9ICJUZW1wZXJhdHVyZSBcbk1vc3MgWDQgKMKwQykiKSArCiAgIHRoZW1lX2dyYXBoc19lbnZfY29uZCgpKwogICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfYmxhbmsoKSwKICAgICAgICBheGlzLnRpdGxlLnggPSBlbGVtZW50X2JsYW5rKCkpKQoKKFBBUl9wbG90XzE5XzIwX1g0IDwtc3VtbWVyXzE5XzIwICU+JSAKICAgIGdncGxvdChhZXMoRGF0ZV9Db21iaW5lZCwgWDQuUEFSKSkgKwogICBnZW9tX3BvaW50KCkrICAjIEFkZCBwb2ludHMgZm9yIHRoZSBkYXRhCiAgIGdlb21fbGluZSgpKyAgIyBhZGQgYSBsaW5lIHRoYXQgam9pbnMgdGhlIHBvaW50cwogICBsYWJzKHggPSAiXG5EYXRlIChkYXkpIiwgeSA9ICJQQVIgXG4owrVtb2wgbS0yIHNeLTEpIikgKwogICB0aGVtZV9ncmFwaHNfZW52X2NvbmQoKSkKICAKKGNvbWJpbmVkX3Bsb3RfMTlfMjBfWDQgPC0gKHRlbXBfcGxvdF8xOV8yMF9YNC9QQVJfcGxvdF8xOV8yMF9YNCkgJiBwbG90X2xheW91dChuY29sID0gMSkpIAoKCmBgYAoKMi4gU3VtbWVyIDIwMjAtMjAyMQoKU2FtcGxlIFgxIChNb3NzKQoKYGBge3J9Cih0ZW1wX3Bsb3RfMjBfMjFfWDEgPC0gc3VtbWVyXzIwXzIxICU+JSAKICAgZ2dwbG90KGFlcyhEYXRlX0NvbWJpbmVkLCBYMS5UZW1wKSkgKwogICBnZW9tX3BvaW50KCkrICAjIEFkZCBwb2ludHMgZm9yIHRoZSBkYXRhCiAgIGdlb21fbGluZSgpKyAgIyBBZGQgYSBsaW5lIHRoYXQgam9pbnMgdGhlIHBvaW50cwogICBnZW9tX2hsaW5lKHlpbnRlcmNlcHQgPSAwLCBjb2xvciA9ICJibHVlIiwgbGluZXR5cGUgPSAiZGFzaGVkIikgKwogICBsYWJzKHggPSAiXG5EYXRlIChkYXkpIiwgeSA9ICJUZW1wZXJhdHVyZSBcbk1vc3MgWDEgKMKwQykiKSArCiAgIHRoZW1lX2dyYXBoc19lbnZfY29uZCgpICsKICAgIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF9ibGFuaygpLAogICAgICAgIGF4aXMudGl0bGUueCA9IGVsZW1lbnRfYmxhbmsoKSkpICAjIFJlbW92ZSBheGlzIGxhYmVsIGFuZCB0ZXh0IGZvciB0aGUgZ3JhcGgKCihQQVJfcGxvdF8yMF8yMV9YMSA8LXN1bW1lcl8yMF8yMSAlPiUgCiAgICBnZ3Bsb3QoYWVzKERhdGVfQ29tYmluZWQsIFgxLlBBUikpICsKICAgZ2VvbV9wb2ludCgpKyAgIyBBZGQgcG9pbnRzIGZvciB0aGUgZGF0YQogICBnZW9tX2xpbmUoKSsgICMgYWRkIGEgbGluZSB0aGF0IGpvaW5zIHRoZSBwb2ludHMKICAgbGFicyh4ID0gIlxuRGF0ZSAoZGF5KSIsIHkgPSAiUEFSIFxuKMK1bW9sIG0tMiBzXi0xKSIpICsKICAgdGhlbWVfZ3JhcGhzX2Vudl9jb25kKCkpCgooY29tYmluZWRfcGxvdF8yMF8yMV9YMSA8LSAodGVtcF9wbG90XzIwXzIxX1gxL1BBUl9wbG90XzIwXzIxX1gxKSAmIHBsb3RfbGF5b3V0KG5jb2wgPSAxKSkKYGBgCgpTYW1wbGUgWDIgKE1vc3MpCgpgYGB7cn0KKHRlbXBfcGxvdF8yMF8yMV9YMiA8LSBzdW1tZXJfMjBfMjEgJT4lIAogICBnZ3Bsb3QoYWVzKERhdGVfQ29tYmluZWQsIFgyLlRlbXApKSArCiAgIGdlb21fcG9pbnQoKSsgICMgQWRkIHBvaW50cyBmb3IgdGhlIGRhdGEKICAgZ2VvbV9saW5lKCkrICAjIEFkZCBhIGxpbmUgdGhhdCBqb2lucyB0aGUgcG9pbnRzCiAgIGdlb21faGxpbmUoeWludGVyY2VwdCA9IDAsIGNvbG9yID0gImJsdWUiLCBsaW5ldHlwZSA9ICJkYXNoZWQiKSArCiAgIGxhYnMoeCA9ICJcbkRhdGUgKGRheSkiLCB5ID0gIlRlbXBlcmF0dXJlIFxuTW9zcyBYMSAowrBDKSIpICsKICAgdGhlbWVfZ3JhcGhzX2Vudl9jb25kKCkgKwogICAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X2JsYW5rKCksCiAgICAgICAgYXhpcy50aXRsZS54ID0gZWxlbWVudF9ibGFuaygpKSkgICMgUmVtb3ZlIGF4aXMgbGFiZWwgYW5kIHRleHQgZm9yIHRoZSBncmFwaAoKKFBBUl9wbG90XzIwXzIxX1gyIDwtc3VtbWVyXzIwXzIxICU+JSAKICAgIGdncGxvdChhZXMoRGF0ZV9Db21iaW5lZCwgWDIuUEFSKSkgKwogICBnZW9tX3BvaW50KCkrICAjIEFkZCBwb2ludHMgZm9yIHRoZSBkYXRhCiAgIGdlb21fbGluZSgpKyAgIyBhZGQgYSBsaW5lIHRoYXQgam9pbnMgdGhlIHBvaW50cwogICBsYWJzKHggPSAiXG5EYXRlIChkYXkpIiwgeSA9ICJQQVIgXG4owrVtb2wgbS0yIHNeLTEpIikgKwogICB0aGVtZV9ncmFwaHNfZW52X2NvbmQoKSkKCihjb21iaW5lZF9wbG90XzIwXzIxX1gyIDwtICh0ZW1wX3Bsb3RfMjBfMjFfWDIvUEFSX3Bsb3RfMjBfMjFfWDIpICYgcGxvdF9sYXlvdXQobmNvbCA9IDEpKQpgYGAKClNhcGxlIFgzIChMaWNoZW4pCgpgYGB7cn0KKHRlbXBfcGxvdF8yMF8yMV9YMyA8LSBzdW1tZXJfMjBfMjEgJT4lIAogICBnZ3Bsb3QoYWVzKERhdGVfQ29tYmluZWQsIFgzLlRlbXApKSArCiAgIGdlb21fcG9pbnQoKSsgICMgQWRkIHBvaW50cyBmb3IgdGhlIGRhdGEKICAgZ2VvbV9saW5lKCkrICAjIEFkZCBhIGxpbmUgdGhhdCBqb2lucyB0aGUgcG9pbnRzCiAgIGdlb21faGxpbmUoeWludGVyY2VwdCA9IDAsIGNvbG9yID0gImJsdWUiLCBsaW5ldHlwZSA9ICJkYXNoZWQiKSArCiAgIGxhYnMoeCA9ICJcbkRhdGUgKGRheSkiLCB5ID0gIlRlbXBlcmF0dXJlIFxuTW9zcyBYMSAowrBDKSIpICsKICAgdGhlbWVfZ3JhcGhzX2Vudl9jb25kKCkgKwogICAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X2JsYW5rKCksCiAgICAgICAgYXhpcy50aXRsZS54ID0gZWxlbWVudF9ibGFuaygpKSkgICMgUmVtb3ZlIGF4aXMgbGFiZWwgYW5kIHRleHQgZm9yIHRoZSBncmFwaAoKKFBBUl9wbG90XzIwXzIxX1gzIDwtc3VtbWVyXzIwXzIxICU+JSAKICAgIGdncGxvdChhZXMoRGF0ZV9Db21iaW5lZCwgWDMuUEFSKSkgKwogICBnZW9tX3BvaW50KCkrICAjIEFkZCBwb2ludHMgZm9yIHRoZSBkYXRhCiAgIGdlb21fbGluZSgpKyAgIyBhZGQgYSBsaW5lIHRoYXQgam9pbnMgdGhlIHBvaW50cwogICBsYWJzKHggPSAiXG5EYXRlIChkYXkpIiwgeSA9ICJQQVIgXG4owrVtb2wgbS0yIHNeLTEpIikgKwogICB0aGVtZV9ncmFwaHNfZW52X2NvbmQoKSkKCihjb21iaW5lZF9wbG90XzIwXzIxX1gzIDwtICh0ZW1wX3Bsb3RfMjBfMjFfWDMvUEFSX3Bsb3RfMjBfMjFfWDMpICYgcGxvdF9sYXlvdXQobmNvbCA9IDEpKQpgYGAKCgoKCgoKCgoK